package com.engine.core.rowMapper;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.core.domain.GenTable;
import com.engine.core.domain.GenTableColumn;
import com.engine.core.domain.JavaFunction;
import com.engine.core.gen.Mysql;
import com.engine.core.util.QueryUtil;
import com.engine.core.util.Utils;
import com.googlecode.aviator.AviatorEvaluator;
import org.apache.commons.lang3.StringUtils;
import org.stringtemplate.v4.ST;

import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JdbcTypeBiz {

    /**
     *  前台定制的数据格式化，目前只支持到时间，日期和数字的格式化
     * @param o
     * @param mappedType
     * @param sqltype
     * @param rs
     * @return
     */
    public static Object userFormat(Object o, MappedType mappedType, int sqltype, ResultSet rs) {
        return o;
    }

    /**
     * 后台统一设置的格式化，根据sqlType类型对数据进行格式化
     * @param o
     * @param sqltype
     * @return
     */
    public static Object sqlTypeFormat(Object o, int sqltype,Map<Integer, String> typeFormat) {
        return o;
    }


    public static String getAllColumns(GenTable genTable){
          StringBuilder builder=new StringBuilder();
        genTable.getColumns().forEach(s->{
            builder.append(s.getColumnName());
            builder.append(",");
        });
        if(builder.length()>1){
            builder.deleteCharAt(builder.length()-1);
        }
        return builder.toString();
    }

    public static String getUserColumns(String columns) {
        StringBuilder builder=new StringBuilder();
        Arrays.asList(columns.split("\\+")).forEach(s->{
            builder.append(s);
            builder.append(",");
        });
        if(builder.length()>1){
            builder.deleteCharAt(builder.length()-1);
        }
        return builder.toString();
    }


    public static Object[] getQueryParams(Map<String, Object> params, String[] dateformat) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_") //DATETIME，DATE
                        || s.getKey().startsWith("P_"))
                       .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());
        Object[] queryObjs=new Object[queryParams.size()];
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String,Object> entry=queryParams.get(i);
            if(entry.getKey().startsWith("I_")){
                 queryObjs[i]= Utils.convert((String)entry.getValue(),"Integer");
            }else if(entry.getKey().startsWith("D_")){
                 queryObjs[i]= Utils.convert((String)entry.getValue(),"Double");
            }else if(entry.getKey().startsWith("L_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Long");
            }else if(entry.getKey().startsWith("F_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Float");
            }else if(entry.getKey().startsWith("T_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Date",dateformat);
            }else if(entry.getKey().startsWith("S_")){
                queryObjs[i]=(String)entry.getValue();
            }else if(entry.getKey().startsWith("P_")){
                queryObjs[i]=entry.getValue();
            }
        }
        return queryObjs;
    }

    public static Object[] getQueryParams(JSONObject params, String[] dateformat) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_") //DATETIME，DATE
                       || s.getKey().startsWith("P_"))
                .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());
        Object[] queryObjs=new Object[queryParams.size()];
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String,Object> entry=queryParams.get(i);
            if(entry.getKey().startsWith("I_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Integer");
            }else if(entry.getKey().startsWith("D_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Double");
            }else if(entry.getKey().startsWith("L_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Long");
            }else if(entry.getKey().startsWith("F_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Float");
            }else if(entry.getKey().startsWith("T_")){
                queryObjs[i]= Utils.convert((String)entry.getValue(),"Date",dateformat);
            }else if(entry.getKey().startsWith("S_")){
                queryObjs[i]=(String)entry.getValue();
            }else if(entry.getKey().startsWith("P_")){
                queryObjs[i]=entry.getValue();
            }
        }
        return queryObjs;
    }

    public static Map<String,Object> getQueryParamsMap(Map<String, Object> params, String[] dateformat) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_")
                        || s.getKey().startsWith("TS_")
                        || s.getKey().startsWith("P_")
                       ) //DATETIME，DATE
                .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());
        Map<String,Object> dmap=new HashMap<>();
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String,Object> entry=queryParams.get(i);
            if(entry.getKey().startsWith("I_")){
                Object obj= Utils.convertValueOrList((String)entry.getValue(),"Integer");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("D_")){
                Object obj= Utils.convertValueOrList((String)entry.getValue(),"Double");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("L_")){
                Object obj= Utils.convertValueOrList((String)entry.getValue(),"Long");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("F_")){
                Object obj= Utils.convertValueOrList((String)entry.getValue(),"Float");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("T_") || entry.getKey().startsWith("TS_")){
                Object obj= Utils.convertValueOrList((String)entry.getValue(),"Date",dateformat);
                dmap.put(entry.getKey().split("_",2)[1],obj);
                if(entry.getKey().startsWith("TS_")){
                    if(Date.class.isInstance(obj)){
                        dmap.put(entry.getKey().split("_",2)[1],new Timestamp(((Date)obj).getTime()));
                    }
                }
            }else if(entry.getKey().startsWith("S_")){
                dmap.put(entry.getKey().split("_",2)[1],(String)entry.getValue());
            }else if(entry.getKey().startsWith("P_")){
                dmap.put(entry.getKey().split("_",2)[1],entry.getValue());
            }
        }
        return dmap;
    }

    public static int getQueryParamsLength(Map<String, Object> params) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_") //Date
                        || s.getKey().startsWith("TS_")
                        || s.getKey().startsWith("P_")
                ) //DATETIME，DATE
                .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());
        return queryParams.size();
    }


    public static Map<String,Object> getQueryParamsMap(JSONObject params, String[] dateformat) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_")
                        || s.getKey().startsWith("TS_")
                        || s.getKey().startsWith("TS_")
                ) //DATETIME，DATE
                .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());
        Map<String,Object> dmap=new HashMap<>();
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String,Object> entry=queryParams.get(i);
            if(entry.getKey().startsWith("I_")){
                Object obj= Utils.convert((String)entry.getValue(),"Integer");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("D_")){
                Object obj= Utils.convert((String)entry.getValue(),"Double");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("L_")){
                Object obj= Utils.convert((String)entry.getValue(),"Long");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("F_")){
                Object obj= Utils.convert((String)entry.getValue(),"Float");
                dmap.put(entry.getKey().split("_",2)[1],obj);
            }else if(entry.getKey().startsWith("T_") || entry.getKey().startsWith("TS_")){
                Object obj= Utils.convert((String)entry.getValue(),"Date",dateformat);
                dmap.put(entry.getKey().split("_",2)[1],obj);
                if(entry.getKey().startsWith("TS_")){
                    dmap.put(entry.getKey().split("_",2)[1],new Timestamp(((Date)obj).getTime()));
                }
            }else if(entry.getKey().startsWith("S_")){
                dmap.put(entry.getKey().split("_",2)[1],(String)entry.getValue());
            }
        }
        return dmap;
    }

    public static TreeMap<String,MappedType> getOneParamsType(Map<String, Object> params, String[] dateformat) throws Exception{
        List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("S_") //string
                        || s.getKey().startsWith("I_") //int
                        || s.getKey().startsWith("D_") //double
                        || s.getKey().startsWith("L_") //long
                        || s.getKey().startsWith("F_") //float
                        || s.getKey().startsWith("T_")
                        || s.getKey().startsWith("S_")
                        || s.getKey().startsWith("TS_")) //DATETIME，DATE
                .sorted((s1,s2)-> (s1.getKey().split("_")[1]).compareTo(s2.getKey().split("_")[1])).collect(Collectors.toList());

        TreeMap<String,MappedType> mappedTypeMap=new TreeMap<>();
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String,Object> entry=queryParams.get(i);
            if(entry.getKey().startsWith("I_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Integer",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("D_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Double",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("L_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Long",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("F_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Float",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("T_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Date",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("S_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("String",entry.getKey().split("_",2)[1]));
            }else if(entry.getKey().startsWith("TS_")){
                mappedTypeMap.put(entry.getKey().split("_",2)[1],new MappedType("Timestamp",entry.getKey().split("_",2)[1]));
            }
        }
        return mappedTypeMap;
    }


    public static MappedType getKeyType(String keyName){
        MappedType mappedType=null;
            if(keyName.startsWith("I_")){
                mappedType=new MappedType("Integer",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("D_")){
                mappedType=new MappedType("Double",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("L_")){
                mappedType=new MappedType("Long",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("F_")){
                mappedType=new MappedType("Float",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("T_")){
                mappedType=new MappedType("Date",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("S_")){
                mappedType=new MappedType("String",keyName.split("_",2)[1]);
            }else if(keyName.startsWith("TS_")){
                mappedType=new MappedType("Timestamp",keyName.split("_",2)[1]);
            }else{
                mappedType=new MappedType("String",keyName);
            }
        return mappedType;
    }

    public static String getTypeByShortName(String typeShortName){
        String mappedType=null;
        switch(typeShortName){
            case "I":{
                mappedType="Integer";
                break;
            }
            case "D":{
                mappedType="Double";
                break;
            }
            case "L":{
                mappedType="Long";
                break;
            }
            case "F":{
                mappedType="Float";
                break;
            }
            case "T":{
                mappedType="Date";
                break;
            }
            case "TS":{
                mappedType="Timestamp";
                break;
            }
            case "S":{
                mappedType="String";
                break;
            }
            default:{
                mappedType=typeShortName;
            }
        }
        return mappedType;
    }


    /**
     * 用于构建sql不需要传数据的列
     * @param params
     * @return
     * @throws Exception
     */
    public static Map<String,String> getUpdateOthersByParams(Map<String, Object> params) throws Exception{
         List<Map.Entry<String,Object>> queryParams=params.entrySet().stream().filter(s->s.getKey().startsWith("O_")).collect(Collectors.toList());
         Map<String,String> others=new TreeMap<>();
        for (int i = 0; i < queryParams.size(); i++) {
            Map.Entry<String, Object> entry = queryParams.get(i);
            others.put(entry.getKey().split("_",2)[1],(String)entry.getValue());
        }
        return others;
    }

    public static Map<String,String> getUpdateOthersByContent(String datas) throws Exception{
        Map<String,String> others=new HashMap<>();
        if(JSONObject.parseObject(datas).containsKey(QueryUtil.UPDATA_OTHERS)){
            JSONObject othersObjects=JSONObject.parseObject(datas).getJSONObject(QueryUtil.UPDATA_OTHERS);
            othersObjects.entrySet().forEach(s->{
                others.put(s.getKey(),s.getValue().toString());
            });
        }
        return others;
    }

    /**
     * 过滤数据库列
     * @param columnMap
     * @param mappedTypeMap
     * @throws Exception
     */
    public static void filterColumns(Map<String,GenTableColumn> columnMap,LinkedHashMap<String,MappedType> mappedTypeMap) throws Exception{
        Iterator<Map.Entry<String, MappedType>> mappedTypeMapIterator =mappedTypeMap.entrySet().iterator();
        while(mappedTypeMapIterator.hasNext()){
            Map.Entry<String, MappedType> entry= mappedTypeMapIterator.next();
            if(!columnMap.containsKey(entry.getKey())){
                mappedTypeMapIterator.remove();
            }
        }
    }

    public static Map<String,String> getMapValueByAttr(String datas,String attr) throws Exception{
        Map<String,String> others=new HashMap<>();
        if(JSONObject.parseObject(datas).containsKey(attr)){
            JSONObject othersObjects=JSONObject.parseObject(datas).getJSONObject(attr);
            othersObjects.entrySet().forEach(s->{
                others.put(s.getKey(),s.getValue().toString());
            });
        }
        return others;
    }



    public static List<Map<String,Object>> getUpdateData(String datas, String[] dateformat) throws Exception{
        Map<String,MappedType> mappedTypeMap=getUpdateParamsTypeByFront(datas);
        List<Map<String,Object>> returnData=new ArrayList<>();
        JSONArray dataArr=JSONArray.parseArray(JSONObject.parseObject(datas).getString(QueryUtil.UPDATA_DATA));
           for (int i = 0; i < dataArr.size(); i++) {
                Map<String,Object> o=new HashMap<>();
                JSONObject dataIt=dataArr.getJSONObject(i);
                Iterator<String> dataItIterator=dataIt.keySet().iterator();
                while(dataItIterator.hasNext()){
                    String  dataItKey=dataItIterator.next();
                    if(mappedTypeMap.containsKey(dataItKey)){
                        if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Date")){
                            o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),"Date",dateformat));
                        }else if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Timestamp")){
                            Date d=(Date) Utils.convert(dataIt.getString(dataItKey),"Date",dateformat);
                            o.put(dataItKey,new Timestamp(d.getTime()));
                        }else{
                            o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),mappedTypeMap.get(dataItKey).getTypeName(),mappedTypeMap.get(dataItKey).getFormat()));
                        }
                    }else{
                        o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),"String"));
                    }
                }
                 returnData.add(o);
           }
           return returnData;

    }

    public static Map<String,MappedType> getUpdateParamsTypeByFront(String datas) throws Exception{
          String columns=JSONObject.parseObject(datas).getString(QueryUtil.QUERY_COLUMNS);
          Map<String,MappedType> columnsMappedType=new TreeMap<>();
          if(StringUtils.isNotBlank(columns)){
              String[] columnsArr=columns.split(",");
              for (int i = 0; i < columnsArr.length; i++) {
                  String column=columnsArr[i];
                  if(column.startsWith("I_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Integer",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Integer",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("D_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Double",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Double",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("L_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Long",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Long",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("F_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Float",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Float",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("T_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Date",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Date",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("S_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("String",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("String",column.split("_",2)[1]));
                      }
                  }else if(column.startsWith("TS_")){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Timestamp",formatCol[0].split("_",2)[1],formatCol[1]));
                      }else{
                          columnsMappedType.put(column.split("_",2)[1],new MappedType("Timestamp",column.split("_",2)[1]));
                      }
                  }else if(column.indexOf('_')==-1){
                      if(column.indexOf(":")>-1){
                          String formatCol[]=column.split(":",2);
                          columnsMappedType.put(column,new MappedType("String",column,formatCol[1]));
                      }else{
                          columnsMappedType.put(column,new MappedType("String",column));
                      }
                  }
              }
          }
          return columnsMappedType;
    }

    public static LinkedHashMap<String,MappedType> getUpdateParamsTypeByDB(String columns,String dataSave,Map<String,GenTableColumn> columnMap,
                                                                           Map<String, JavaFunction> functionMap,Map<String,String> others) throws Exception{
        LinkedHashMap<String,MappedType> columnsMappedType=new LinkedHashMap<>();
        String columnsArr[]=null;
        if(Utils.nullDefault(columns).length()==0){
            if(JSONObject.isValidArray(dataSave)){
                JSONArray dataSaveJSONArray=JSONArray.parseArray(dataSave);
                if(JSONObject.isValidObject(dataSaveJSONArray.getString(0))){
                    JSONObject jsonObject=dataSaveJSONArray.getJSONObject(0);
                    columnsArr= jsonObject.keySet().toArray(new String[jsonObject.keySet().size()]);
                }
            }else{
                if(JSONObject.isValidObject(dataSave)){
                    JSONObject jsonObject=JSONArray.parseObject(dataSave);
                    columnsArr=jsonObject.keySet().toArray(new String[jsonObject.keySet().size()]);
                }
            }
        }else if(JSONObject.isValidArray(columns)){
            JSONArray columnsArray=JSONArray.parseArray(columns);
            columnsArr=new String[columnsArray.size()];
            for (int i = 0; i < columnsArray.size(); i++) {
                if(columnsArray.get(i) instanceof JSONObject){
                    JSONObject jo=columnsArray.getJSONObject(i);
                    if(jo.containsKey("column")){
                        String column = jo.getString("column");
                        String funOrder = jo.getString("funOrder");
                        MappedType mappedType= JdbcTypeBiz.getKeyType(column);
                        if(jo.containsKey("function")){
                            String function=jo.getString("function");
                            JavaFunction javaFunction=new JavaFunction(function,mappedType.getColumn(),1);
                            javaFunction.setOrderBy(Utils.getInt(funOrder,0));
                            functionMap.put(mappedType.getColumn(),javaFunction);
                        }
                        if(jo.containsKey("dbfunction")){
                            String function=jo.getString("dbfunction");
                            others.put(mappedType.getColumn(),function);
                        }
                        columnsArr[i]=column;
                    }
                }else{
                    columnsArr[i]=columnsArray.getString(i);
                }

            }
        }else{
            columnsArr=columns.split(",");
        }
        if (columnsArr != null) {
            for (int i = 0; i < columnsArr.length; i++) {
                MappedType mappedType= JdbcTypeBiz.getKeyType(columnsArr[i]);
                String columnName = mappedType.getColumn();
                if(columnMap.get(columnName)!=null){
                    columnsMappedType.put(columnName,new MappedType(Mysql.javaTypeByColumnType(columnMap.get(columnName).getColumnType())
                            ,columnName,columnMap.get(columnName)));
                }else{
                    columnsMappedType.put(columnName,mappedType);
                }
            }
        }
        return columnsMappedType;
    }

    public static List<Map<String,Object>> getUpdateDataByDB(String datas, String[] dateformat,LinkedHashMap<String,MappedType> mappedTypeMap,Map<String, JavaFunction> functionMap) throws Exception{
        List<Map<String,Object>> returnData=new ArrayList<>();
        if(JSONObject.isValidObject(datas)){

            Map<String,Object> o=new HashMap<>();
            JSONObject dataIt=JSONObject.parseObject(datas);
            Iterator<String> dataItIterator=dataIt.keySet().iterator();
            while(dataItIterator.hasNext()){
                String  dataItKey=dataItIterator.next();
                if(mappedTypeMap.containsKey(dataItKey)){
                    if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Date")){
                        o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),"Date",dateformat));
                    }else if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Timestamp")){
                        Date d=(Date) Utils.convert(dataIt.getString(dataItKey),"Date",dateformat);
                        o.put(dataItKey,new Timestamp(d.getTime()));
                    }else{
                        o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),mappedTypeMap.get(dataItKey).getTypeName(),mappedTypeMap.get(dataItKey).getFormat()));
                    }
                }else{
                    MappedType mappedType= JdbcTypeBiz.getKeyType(dataItKey);
                    String paramName=mappedType.getColumn();
                    Object objs=Utils.convert(dataIt.getString(paramName), mappedType.getTypeClass(),dateformat);
                    o.put(dataItKey,objs);
                }
            }
            excecuteFunMap(o,functionMap,dateformat,mappedTypeMap);
            returnData.add(o);
        }else if(JSONObject.isValidArray(datas)){
            JSONArray dataArr=JSONArray.parseArray(datas);
            for (int i = 0; i < dataArr.size(); i++) {
                Map<String,Object> o=new TreeMap<>();
                if(JSONObject.isValidObject(dataArr.getString(i))){
                    JSONObject dataIt=dataArr.getJSONObject(i);
                    Iterator<String> dataItIterator=dataIt.keySet().iterator();
                    while(dataItIterator.hasNext()){
                        String  dataItKey=dataItIterator.next();
                        if(mappedTypeMap.containsKey(dataItKey)){
                            if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Date")){
                                o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),"Date",dateformat));
                            }else if(mappedTypeMap.get(dataItKey).getTypeName().equalsIgnoreCase("Timestamp")){
                                Date d=(Date) Utils.convert(dataIt.getString(dataItKey),"Date",dateformat);
                                o.put(dataItKey,new Timestamp(d.getTime()));
                            }else{
                                o.put(dataItKey,Utils.convert(dataIt.getString(dataItKey),mappedTypeMap.get(dataItKey).getTypeName(),mappedTypeMap.get(dataItKey).getFormat()));
                            }
                        }else{
                            MappedType mappedType= JdbcTypeBiz.getKeyType(dataItKey);
                            String paramName=mappedType.getColumn();
                            Object objs=Utils.convert(dataIt.getString(paramName), mappedType.getTypeClass(),dateformat);
                            o.put(dataItKey,objs);
                        }
                    }
                    excecuteFunMap(o,functionMap,dateformat,mappedTypeMap);
                    returnData.add(o);
                }else if(JSONArray.isValidArray(dataArr.getString(i))){
//                    JSONArray da=dataArr.getJSONArray(i);
//                    Iterator<String> mappedTypeMapIterator= mappedTypeMap.keySet().iterator();
//                    int idx=0;
//                    Map<String,Integer> columnIdex=new HashMap<>();
//                    while(mappedTypeMapIterator.hasNext()){
//                        String keyColumn=mappedTypeMapIterator.next();
//                        MappedType mappedType= JdbcTypeBiz.getKeyType(keyColumn);
//                        String paramName=mappedType.getColumn();
//                        Object objs=Utils.convert(da.getString(idx), mappedType.getTypeClass(),dateformat);
//                        o.put(paramName,objs);
//                        columnIdex.put(paramName, idx);
//                        idx++;
//                    }
//                    final Map<String,Object> env=new HashMap<>();
//                    env.put("params",o);
//                    env.putAll(o);
//                    functionMap.entrySet().forEach(s->{
//                        JavaFunction function = s.getValue();
//                        Integer columnIndex=columnIdex.get(s.getKey());
//                        if(columnIndex!=null){
//                            env.put("value",da.getString(columnIndex));
//                        }
//                        ST st=new ST(function.toString(),'$','$');
//                        env.entrySet().forEach(stp->{
//                            st.add(stp.getKey(),stp.getValue());
//                        });
//                        Object exco= AviatorEvaluator.execute(st.render(), env);
//                        o.put(s.getKey(),exco);
//                    });
//                    returnData.add(o);
                }
            }
        }
        return returnData;
    }

    public static void excecuteFunMap(Map<String,Object> o, Map<String, JavaFunction> functionMap,String[] dateformat,LinkedHashMap<String,MappedType> mappedTypeMap) throws Exception {
        List<String> newKeyList=new ArrayList<String>(functionMap.keySet());
        newKeyList=newKeyList.stream().sorted((s1,s2)->{
            if(s1.compareTo(s2)==0){
                JavaFunction o1=functionMap.get(s1);
                JavaFunction o2=functionMap.get(s2);
                return o1.getOrderBy().compareTo(o2.getOrderBy());
            }else{
                return s1.compareTo(s2);
            }
        }).collect(Collectors.toList());

        final Map<String,Object> env=new HashMap<>();
        env.put("params",o);
        env.putAll(o);

        newKeyList.forEach(s->{
            String key=s;
            JavaFunction function = functionMap.get(s);
            env.put("value",o.get(key));
            ST st=new ST(function.toString(),'$','$');
            env.entrySet().forEach(stp->{
                st.add(stp.getKey(),stp.getValue());
            });
            Object exco= AviatorEvaluator.execute(st.render(), env);
            String paramName=key;
            if(mappedTypeMap.containsKey(paramName)){
                try {
                    Object objs=Utils.convert(String.valueOf(exco), mappedTypeMap.get(paramName).getTypeClass(),dateformat);
                    o.put(paramName,objs);
                } catch (Exception e) {
                }
            }else{
                o.put(paramName,exco);
            }
        });
    }

    /**
     * 是否含有sql注入，返回true表示含有
     *
     * @param obj
     * @return
     */
    public static boolean containsSqlInjection(Object obj) {
        Pattern pattern = Pattern.compile(
                "\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or)\\b|(\\*|;|\\+|'|%)");
        Matcher matcher = pattern.matcher(obj.toString());
        return matcher.find();
    }

    public static boolean containsColumnInjection(Object obj) {
        Pattern pattern = Pattern.compile(
                "\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or)\\b|(;|'|%)");
        Matcher matcher = pattern.matcher(obj.toString());
        return matcher.find();
    }

}
